from typing import Annotated, Optional, List, Dict
from fastapi import Depends, FastAPI, HTTPException, Query
from sqlmodel import Field, Session, SQLModel, create_engine, select, Relationship
from datetime import datetime

# 登录成功响应模型
class RespJsonLogin(SQLModel):
    code: int = Field(default=200)
    msg: str = Field(default="登录成功")
    access_token: str
    token_type: str = Field(default="bearer")


"""用户角色关系表

Keyword arguments:
UserRoleLinkBase -- 用户角色关系基础模型
UserRoleLinkCreate -- 用户角色关系创建模型
UserRoleLinkUpdate -- 用户角色关系更新模型
UserRoleLinkRead -- 用户角色关系读取模型
RespJsonUserRoleLink -- 用户角色关系响应模型
UserRoleLink -- 用户角色关系表
Return: return_description
"""


class SystemUserRoleLinkBase(SQLModel):
    user_id: int | None = Field(
        nullable=False, foreign_key="system_user.id", ondelete="CASCADE", default=None)  # 用户id
    role_id: int | None = Field(
        nullable=False, foreign_key="system_role.id", ondelete="CASCADE", default=None)  # 角色id


class SystemUserRoleLinkCreate(SystemUserRoleLinkBase):
    pass


class SystemUserRoleLinkUpdate(SystemUserRoleLinkBase):
    pass


class SystemUserRoleLinkRead(SystemUserRoleLinkBase):
    id: int | None = Field(default=None, primary_key=True, index=True)


class SystemRespJsonUserRoleLink(SQLModel):
    code: int = Field(default=200)
    msg: str = Field(default="查询成功")
    data: List[SystemUserRoleLinkRead] = []


class SystemUserRoleLink(SQLModel, table=True):
    __tablename__ = "system_userrolelink"    # 表名
    __table_args__ = {'comment': '用户与角色关系表，存储用户关联的角色信息'}

    id: int | None = Field(default=None, primary_key=True, index=True)
    user_id: int = Field(
        nullable=False, foreign_key="system_user.id", ondelete="CASCADE")  # 用户id
    role_id: int = Field(
        nullable=False, foreign_key="system_role.id", ondelete="CASCADE")  # 角色id

    def __str__(self):
        return 'UserToRole(user_id:{},role_id:{})'.format(self.user_id, self.role_id)


"""系统用户表

Keyword arguments:
SystemUserBase -- 系统用户基础模型
SystemUserCreate -- 系统用户创建模型
SystemUserUpdate -- 系统用户更新模型
SystemUserRead -- 系统用户读取模型
SystemUserContent -- 系统用户内容模型
SystemUserInfoRead -- 系统用户信息读取模型
SystemUserInfo -- 系统用户信息模型
SystemUserModifyPassword -- 系统用户修改密码模型
RespJsonUser -- 系统用户响应模型
SystemUser -- 系统用户模型（表）
Return: return_description
"""


class SystemUserBase(SQLModel):
    username: str = Field(max_length=50, nullable=False,
                          index=True, unique=True, default="admin")  # 用户名
    name: str = Field(max_length=50, nullable=False, default="管理员")  # 姓名
    org_id: int | None = Field(
        nullable=True, foreign_key="system_org.id", ondelete="CASCADE", default=1)  # 所属组织机构id
    is_active: bool = Field(nullable=False, default=True)  # 状态，1：启用，0：禁用


class SystemUserCreate(SystemUserBase):
    role_ids: List[int] = None


class SystemUserUpdate(SystemUserBase):
    role_ids: List[int] = None


class SystemUserModifyPassword(SQLModel):
    old_password: str = Field(min_length=6)
    new_password: str = Field(min_length=6)


class SystemUserRead(SystemUserBase):
    id: int | None = Field(default=None, primary_key=True, index=True)
    org_name: str | None = Field(
        nullable=True, foreign_key="system_org.name", ondelete="SET NULL")  # 所属组织机构名称
    create_id: int | None = Field(
        nullable=True, foreign_key="system_user.id", ondelete="SET NULL")  # 创建人
    creator: str | None = Field(
        nullable=True, foreign_key="system_user.name", ondelete="SET NULL")  # 创建人名称
    createtime: datetime = Field(
        default_factory=datetime.now)  # 创建时间
    update_id: int | None = Field(
        nullable=True, foreign_key="system_user.id", ondelete="SET NULL")  # 更新人
    updater: str | None = Field(
        nullable=True, foreign_key="system_user.name", ondelete="SET NULL")  # 更新人名称
    updatetime: datetime = Field(
        default_factory=datetime.now)  # 更新时间
    roles: List | None = []


class SystemUserInfo(SystemUserBase):
    id: int | None = Field(default=None, primary_key=True, index=True)
    org_name: str | None
    roles: List | None = []


class SystemUserContent(SQLModel):
    total: int = Field(default=0)
    totalPages: int = Field(default=1)
    items: List[SystemUserRead] = []


class RespJsonUser(SQLModel):
    code: int = Field(default=200)
    msg: str = Field(default="查询成功")
    data: SystemUserContent | list = {}


class RespJsonUserInfo(SQLModel):
    code: int = Field(default=200)
    msg: str = Field(default="查询成功")
    data: SystemUserInfo = {}


class SystemUser(SystemUserBase, table=True):
    __tablename__ = "system_user"    # 表名
    __table_args__ = {'comment': '用户表，存储后台用户信息'}

    id: int | None = Field(default=None, primary_key=True, index=True)
    password: str = Field(max_length=255, nullable=False,
                          default="123456")  # 密码
    is_deleted: bool = Field(nullable=False, default=False)  # 状态，0:正常，1:已删除
    create_id: int | None = Field(
        nullable=True, foreign_key="system_user.id", ondelete="SET NULL")  # 创建人
    createtime: datetime = Field(
        default_factory=datetime.now)  # 创建时间
    update_id: int | None = Field(
        nullable=True, foreign_key="system_user.id", ondelete="SET NULL")  # 更新人
    updatetime: datetime = Field(
        default_factory=datetime.now)  # 更新时间

    roles: list["SystemRole"] = Relationship(
        back_populates="users", link_model=SystemUserRoleLink)

    def update(self):
        self.updatetime = datetime.now()

    def __str__(self):
        return 'User(name:{})'.format(self.name)


"""组织机构关系表

Keyword arguments:
SystemOrgBase -- 组织机构基础模型
SystemOrgCreate -- 组织机构创建模型
SystemOrgUpdate -- 组织机构更新模型
SystemOrgRead -- 组织机构读取模型
RespJsonOrg -- 组织机构响应模型
SystemOrg -- 组织机构模型（表）
Return: return_description
"""


class SystemOrgBase(SQLModel):
    name: str = Field(max_length=50, nullable=False, default="机构名称")  # 组织机构名称
    code: str = Field(max_length=50, nullable=False, default="1")  # 组织机构编码
    parent_id: int | None = Field(
        nullable=True, foreign_key="system_org.id", ondelete="CASCADE", default=None)  # 父级组织机构
    order: int = Field(nullable=False, default=1)  # 排序值
    is_active: bool = Field(nullable=False, default=True)  # 状态：1：启用，0：禁用
    notes: str = Field(max_length=255, default="备注")  # 备注


class SystemOrgCreate(SystemOrgBase):
    pass


class SystemOrgUpdate(SystemOrgBase):
    pass


class SystemOrgRead(SystemOrgBase):
    id: int | None = Field(default=None, primary_key=True, index=True)
    # 如果没有子节点，children 为 None，不自动返回
    children: Optional[List["SystemOrgRead"]] = None


class RespJsonOrg(SQLModel):
    code: int = Field(default=200)
    msg: str = Field(default="查询成功")
    data: List[SystemOrgRead] = []


class SystemOrg(SystemOrgBase, table=True):
    __tablename__ = "system_org"    # 表名
    __table_args__ = {'comment': '组织机构表，存储系统组织机构信息'}

    id: int | None = Field(default=None, primary_key=True, index=True)
    create_id: int | None = Field(
        nullable=True, foreign_key="system_user.id", ondelete="SET NULL")  # 创建人
    createtime: datetime = Field(
        default_factory=datetime.now)  # 创建时间
    update_id: int | None = Field(
        nullable=True, foreign_key="system_user.id", ondelete="SET NULL")  # 更新人
    updatetime: datetime = Field(
        default_factory=datetime.now)  # 更新时间

    def update(self):
        self.updatetime = datetime.now()

    def __str__(self):
        return 'Org(name:{})'.format(self.name)


"""角色菜单关系表

Keyword arguments:
SystemRoleToMenuBase -- 角色菜单关系基础模型
SystemRoleToMenuCreate -- 角色菜单关系创建模型
SystemRoleToMenuUpdate -- 角色菜单关系更新模型
SystemRoleToMenuRead -- 角色菜单关系读取模型
RespJsonRoleToMenu -- 角色菜单关系响应模型
SystemRoleToMenu -- 角色菜单关系模型（表）
Return: return_description
"""


class SystemRoleMenuLinkBase(SQLModel):
    role_id: int | None = Field(
        nullable=False, foreign_key="system_role.id", ondelete="CASCADE", default=None)  # 角色id
    menu_id: int | None = Field(
        nullable=False, foreign_key="system_menu.id", ondelete="CASCADE", default=None)  # 菜单id


class SystemRoleMenuLinkCreate(SystemRoleMenuLinkBase):
    pass


class SystemRoleMenuLinkUpdate(SystemRoleMenuLinkBase):
    pass


class SystemRoleMenuLinkRead(SystemRoleMenuLinkBase):
    id: int | None = Field(default=None, primary_key=True, index=True)


class RespJsonRoleMenuLink(SQLModel):
    code: int = Field(default=200)
    msg: str = Field(default="查询成功")
    data: List[SystemRoleMenuLinkRead] = []


class SystemRoleMenuLink(SystemRoleMenuLinkBase, table=True):
    __tablename__ = "system_rolemenulink"    # 表名
    __table_args__ = {'comment': '角色与菜单关系表，存储角色关联的菜单信息'}

    id: int | None = Field(default=None, primary_key=True, index=True)

    def __str__(self):
        return 'RoleMenuLink(role_id:{},menu_id:{})'.format(self.role_id, self.menu_id)


"""系统角色表

Keyword arguments:
SystemRoleBase -- 角色基础模型
SystemRoleCreate -- 角色创建模型
SystemRoleUpdate -- 角色更新模型
SystemRoleRead -- 角色读取模型
SystemRoleContent -- 角色内容模型
RespJsonRole -- 角色响应模型
SystemRole -- 角色模型（表）
Return: return_description
"""


class SystemRoleBase(SQLModel):
    name: str = Field(max_length=50, nullable=False, default="超级管理员")  # 角色名称
    code: str = Field(max_length=50, nullable=False, default="1")  # 角色编码
    is_active: bool = Field(nullable=False, default=True)  # 状态，1：启用，0：禁用


class SystemRoleCreate(SystemRoleBase):
    menu_ids: List[int] = []


class SystemRoleUpdate(SystemRoleBase):
    menu_ids: List[int] = []


class SystemRoleRead(SystemRoleBase):
    id: int | None = Field(default=None, primary_key=True, index=True)
    creator: str | None = Field(
        nullable=True, foreign_key="system_user.name", ondelete="SET NULL")  # 创建人
    updater: str | None = Field(
        nullable=True, foreign_key="system_user.name", ondelete="SET NULL")  # 更新人
    createtime: datetime = Field(
        default_factory=datetime.now)  # 创建时间
    updatetime: datetime = Field(
        default_factory=datetime.now)  # 更新时间
    menu_ids: list | None = []

class SystemRoleContent(SQLModel):
    total: int = Field(default=0)
    totalPages: int = Field(default=1)
    items: List[SystemRoleRead] = []


class RespJsonRole(SQLModel):
    code: int = Field(default=200)
    msg: str = Field(default="查询成功")
    data: SystemRoleContent | list = []


class SystemRole(SystemRoleBase, table=True):
    __tablename__ = "system_role"    # 表名
    __table_args__ = {'comment': '角色表，存储系统角色信息'}

    id: int | None = Field(default=None, primary_key=True, index=True)
    create_id: int | None = Field(
        nullable=True, foreign_key="system_user.id", ondelete="SET NULL")  # 创建人
    createtime: datetime = Field(
        default_factory=datetime.now)  # 创建时间
    update_id: int | None = Field(
        nullable=True, foreign_key="system_user.id", ondelete="SET NULL")  # 更新人
    updatetime: datetime = Field(
        default_factory=datetime.now)  # 更新时间

    menus: list["SystemMenu"] = Relationship(
        back_populates="roles", link_model=SystemRoleMenuLink)
    users: list[SystemUser] = Relationship(
        back_populates="roles", link_model=SystemUserRoleLink)

    def update(self):
        self.updatetime = datetime.now()

    def __str__(self):
        return 'Role(name:{})'.format(self.name)


"""系统菜单表

Keyword arguments:
SystemMenuBase -- 系统菜单基础模型
SystemMenuCreate -- 系统菜单创建模型
SystemMenuUpdate -- 系统菜单更新模型
SystemMenuRead -- 系统菜单读取模型
RespJsonMenu -- 系统菜单响应模型
SystemMenu -- 系统菜单模型（表）
Return: return_description
"""


class SystemMenuBase(SQLModel):
    name: str = Field(max_length=50, nullable=False, default="字典管理")  # 菜单名称
    icon: str | None = Field(max_length=50, default="dict")  # 图标名称
    url: str | None = Field(max_length=50, default="dict")  # 菜单路由
    order: int = Field(nullable=False, default=4)  # 排序值
    parent_id: int | None = Field(
        nullable=True, foreign_key="system_menu.id", ondelete="CASCADE")  # 父级菜单
    is_active: bool = Field(nullable=False, default=True)  # 状态：1启用，0禁用


class SystemMenuCreate(SystemMenuBase):
    pass


class SystemMenuUpdate(SystemMenuBase):
    pass


class SystemMenuRead(SystemMenuBase):
    id: int | None = Field(default=None, primary_key=True, index=True)
    children: Optional[List["SystemMenuRead"]] = None  # 子菜单


class RespJsonMenu(SQLModel):
    code: int = Field(default=200)
    msg: str = Field(default="查询成功")
    data: List[SystemMenuRead] = []


class SystemMenu(SystemMenuBase, table=True):
    __tablename__ = "system_menu"    # 表名
    __table_args__ = {'comment': '菜单表，存储系统菜单信息'}

    id: int | None = Field(default=None, primary_key=True, index=True)
    create_id: int | None = Field(
        nullable=True, foreign_key="system_user.id", ondelete="SET NULL")  # 创建人
    createtime: datetime = Field(
        default_factory=datetime.now)  # 创建时间
    update_id: int | None = Field(
        nullable=True, foreign_key="system_user.id", ondelete="SET NULL")  # 更新人
    updatetime: datetime = Field(
        default_factory=datetime.now)  # 更新时间

    roles: list["SystemRole"] = Relationship(
        back_populates="menus", link_model=SystemRoleMenuLink)

    def __str__(self):
        return 'Menu(name:{})'.format(self.name)


"""
系统字典表

Keyword arguments:
SystemDictBase -- 系统字典基础模型
SystemDictCreate  -- 系统字典创建模型
SystemDictUpdate -- 系统字典更新模型
SystemDictRead -- 系统字典读取模型
SystemDictContent -- 系统字典内容模型
RespJsonDic -- 系统字典响应模型
SystemDict -- 系统字典模型（数据表）
Return: return_description
"""


class SystemDictBase(SQLModel):
    name: str = Field(max_length=50, nullable=False, default="男")  # 字典名称
    code: int = Field(nullable=False, default=1)  # 字典编码
    type: str = Field(max_length=50, nullable=False, default="性别")  # 字典类型名称
    type_code: str = Field(max_length=50, nullable=False,
                           default="sex")  # 字段类型编码


class SystemDictCreate(SystemDictBase):
    pass


class SystemDictUpdate(SystemDictBase):
    pass


class SystemDictRead(SystemDictBase):
    id: int | None = Field(default=None, primary_key=True, index=True)
    creator: str | None = Field(
        nullable=True, foreign_key="system_user.name", ondelete="SET NULL")  # 创建人
    updater: str | None = Field(
        nullable=True, foreign_key="system_user.name", ondelete="SET NULL")  # 更新人
    createtime: datetime = Field(
        default_factory=datetime.now)  # 创建时间
    updatetime: datetime = Field(
        default_factory=datetime.now)  # 更新时间


class SystemDictContent(SQLModel):
    total: int = Field(default=0)
    totalPages: int = Field(default=1)
    items: List[SystemDictRead] = []

class RespJsonDic(SQLModel):
    code: int = Field(default=200)
    msg: str = Field(default="查询成功")
    data: SystemDictContent | list = {}


class SystemDict(SystemDictBase, table=True):
    __tablename__ = "system_dict"    # 表名
    __table_args__ = {'comment': '字典表，存储系统字典信息'}

    id: int | None = Field(default=None, primary_key=True, index=True)
    create_id: int | None = Field(
        nullable=True, foreign_key="system_user.id", ondelete="SET NULL")  # 创建人
    update_id: int | None = Field(
        nullable=True, foreign_key="system_user.id", ondelete="SET NULL")  # 更新人
    createtime: datetime = Field(
        default_factory=datetime.now)  # 创建时间
    updatetime: datetime = Field(
        default_factory=datetime.now)  # 更新时间

    def update(self):
        self.updatetime = datetime.now()

    def __str__(self):
        return 'SystemDict(name:{})'.format(self.name)
